package mylab.utils.common;

import com.google.common.base.Splitter;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.net.*;
import java.util.Enumeration;
import java.util.List;
import java.util.stream.Collectors;


public class NetUtil extends cn.hutool.core.net.NetUtil {

    public static String getHostName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            return null;
        }
    }

    public static NetworkInterface getFirstNetworkInterface() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                    //filter
                } else {
                    return netInterface;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getHostIP() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                    //filter
                } else {
                    Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        ip = addresses.nextElement();
                        if (ip instanceof Inet4Address) {
                            return ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getHostMac() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            byte[] mac;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                    //filter
                } else {
                    mac = netInterface.getHardwareAddress();
                    if (mac != null) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < mac.length; i++) {
                            sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
                        }
                        if (sb.length() > 0) {
                            return sb.toString();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static List<URI> getUris(String string) {
        return Splitter.on(";").omitEmptyStrings().splitToList(string).stream().map(NetUtil::getUri).collect(Collectors.toList());
    }

    public static URI getUri(String string) {
        return URI.create(string);
    }

    public static URI getFirstUri(String string) {
        return getUris(string).stream().findFirst().get();
    }

    public static List<Broker> getBrokers(String string) {
        return Splitter.on(";").omitEmptyStrings().splitToList(string).stream().map(NetUtil::getBroker).collect(Collectors.toList());
    }

    public static Broker getBroker(String string) {
        List<String> strs = Splitter.on(":").omitEmptyStrings().splitToList(string);
        return new Broker(strs.get(0), Integer.parseInt(strs.get(1)));
    }

    public static Broker getFirstBroker(String string) {
        return getBrokers(string).stream().findFirst().get();
    }


    @Data
    @AllArgsConstructor
    public static class Broker {
        private String host;
        private int port;
    }


}
